<?php

namespace App\Service\Cruise\Check;

use App\Enums\BaseErrorCode;
use App\Enums\Cruise\ErrCode;
use App\Exceptions\Custom\ResponseHttpException;
use App\Library\Rms\RmsShopApi;
use App\Library\Rms\RmsUserApi;
use App\Models\Common\ConfigModel;
use App\Models\Common\FsCompanyModel;
use App\Models\Common\FsCompanyUserMappingModel;
use App\Models\Common\ResourcesModel;
use App\Models\Cruise\CruiseCheckDetailModel;
use App\Models\Cruise\CruiseCheckSelfDetailModel;
use App\Models\Cruise\CruiseCheckTaskModel;
use App\Models\Cruise\CruiseOrderExamineLogModel;
use App\Models\Cruise\CruiseOrderModel;
use App\Models\Cruise\CruiseOrderProcessModel;
use App\Models\Cruise\CruiseTaskOrderMappingModel;
use App\Models\Cruise\CruiseTemplateModel;
use App\Models\Kms\User\KmsUser;
use App\Models\OpenShop\InvestmentPromotion\OpenShopMainProcessModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopOrganizationManageUserModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopSignOrderModel;
use App\Models\Shop\ShopModel;
use App\Service\BaseService;
use App\Service\Common\MakeQRCodeService;
use App\Service\Cruise\Disinfect\CruiseDisinfectService;
use App\Service\Cruise\Mission\CheckInputService;
use App\Service\Cruise\Mission\CruiseMissionService;
use App\Service\OpenShop\User\RmsUserService;
use Carbon\Carbon;
use Exception;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Kuafu\Snow\KfSnow;

class CruiseOrderService extends BaseService
{


    const CRUISE_CHECK_KEY                   = 'KF_CRUISE_CHECK';             //解码钥匙
    const CRUISE_CHECK_SCAN_QRCODE_AGREEMENT = 'JH://checkManagerQrCode?';    //稽核人员扫码协议


    /**
     * 常规任务巡检
     * @param int $shopId 多重含义
     * @param $userId
     * @param int $type
     * @param int $selfTaskId
     * @return array|int[]
     * @throws GuzzleException
     */
    public static function addTask(int $shopId, $userId, int $type = 0, int $selfTaskId = 0): array
    {
        $taskExist = false;
        $orderId   = 0;
        $orderNo   = '';
        switch ($type) {
            case CruiseTemplateModel::TYPE_5:
                $cruiseCheckSelfDetailModel = CruiseCheckSelfDetailModel::query()
                    ->with(['cruiseCheckSelfTaskRel'])
                    ->find($selfTaskId);
                if ($cruiseCheckSelfDetailModel->cruiseOrderId) {
                    //已有任务
                    $taskExist = true;
                    $orderId   = $cruiseCheckSelfDetailModel->cruiseOrderId;
                } else {
                    $template = CruiseTemplateModel::query()->find((int)optional($cruiseCheckSelfDetailModel->cruiseCheckSelfTaskRel)->templateId);
                    if (null == $template) {
                        self::throwErr('模版获取失败');
                    }
                    $templateId           = $template->id;
                    $cruiseCheckCompanyId = $cruiseCheckSelfDetailModel->cruiseCheckCompanyId;
                }
                $sysTemplate = CruiseTemplateModel::SYS_TEMPLATE_FACTORY_SELF;
                break;
            default:
                //根据门店ID获得门店编号   排除作废订单
                $shopInfo = (new RmsShopApi())->getShopByIds([$shopId])['data']['shopList'][0] ?? [];
                $shopCode = $shopInfo['shopCode'] ?? 0;
                //获得开店订单
                $orderNo = OpenShopSignOrderModel::query()
                    ->where('shopCode', $shopCode)
                    //->where('status', SignOrderEnum::ORDER_STATUS_COMPLETE)
                    ->value('orderNo');

                if (!$shopInfo || !$shopCode || !$orderNo) {
                    throw new ResponseHttpException(BaseErrorCode::$ERROR_OCCURRED, null, "查询不到该门店信息或该门店还在筹备中");
                }

                CruiseOrderModel::query()
                    ->where('type', CruiseOrderModel::TYPE_CHECK)
                    ->where('shopId', $shopId)
                    ->whereIn('status', [CruiseOrderModel::STATUS_NOT_MODIFY, CruiseOrderModel::STATUS_NOT_REVIEW, CruiseOrderModel::STATUS_NOT_SUBMIT])
                    ->with(['checkTaskDetailRel'])
                    ->get()
                    ->each(function (CruiseOrderModel $cruiseOrderModel) use (&$taskExist, &$orderId) {
                        $orderId = $cruiseOrderModel->id;
                        if ((int)optional($cruiseOrderModel->checkTaskDetailRel)->sysTemplate == CruiseTemplateModel::SYS_TEMPLATE_COMMON) {
                            $taskExist = true;
                        }
                    });
                $sysTemplate          = CruiseTemplateModel::SYS_TEMPLATE_COMMON;
                $templateId           = CruiseTemplateModel::getTemplateIdBySysTemplate($sysTemplate);
                $template             = CruiseTemplateModel::query()->find($templateId);
                $cruiseCheckCompanyId = 0;
        }

        //已有任务直接返回
        if ($taskExist) {
            //throw new ResponseHttpException(BaseErrorCode::$ERROR_OCCURRED, null, "该任务已存在");
            return ['id' => $orderId];
        }

        DB::beginTransaction();

        try {

            //添加任务表
            $taskName        = $template->name;
            $cruiseCheckTask = CruiseCheckTaskModel::add($taskName, $templateId);

            $cruiseOrder = self::addTaskDb($orderNo, $shopId, $cruiseCheckTask->id, $userId, '', $sysTemplate, CruiseCheckDetailModel::CHECK_TYPE_COMMON, $templateId, $cruiseCheckCompanyId);

            if ($type == CruiseTemplateModel::TYPE_5) {
                //数据补充
                CruiseCheckSelfDetailModel::query()
                    ->where('id', $selfTaskId)
                    ->update([
                        'cruiseOrderId' => $cruiseOrder->id,
                    ]);
            }
            DB::commit();
        } catch (\Exception $exception) {
            Log::warning($exception);
            DB::rollBack();
            throw new ResponseHttpException(BaseErrorCode::$ERROR_OCCURRED, null, "创建任务失败");
        }
        return ['id' => $cruiseOrder->id];
    }

    public static function addTaskDb(string $orderNo, int $shopId, int $cruiseCheckTaskId, int $userId, string $companyId, int $sysTemplate, int $checkType = CruiseCheckDetailModel::CHECK_TYPE_COMMON, int $templateId = 0, int $cruiseCheckCompanyId = 0, string $relationCode = ''): CruiseOrderModel
    {

        // 是否自动领取任务
        $receiveTask = false;
        $dealName    = '';

        switch ($sysTemplate) {
            case CruiseTemplateModel::SYS_TEMPLATE_FACTORY_SELF:
                $orderNo = '';
                $status  = CruiseOrderModel::STATUS_NOT_SUBMIT;
                $type    = CruiseOrderModel::TYPE_COMPANY_CHECK;
                break;
            case CruiseTemplateModel::SYS_TEMPLATE_FACTORY_SPECIAL:
                $orderNo = '';
                if ($checkType == CruiseCheckDetailModel::CHECK_TYPE_INSIDE) {
                    $status = CruiseOrderModel::STATUS_NOT_SUBMIT;
                } else {
                    $status = CruiseOrderModel::STATUS_COLLECTED;
                }
                $type    = CruiseOrderModel::TYPE_COMPANY_CHECK;
                break;
            case CruiseTemplateModel::SYS_TEMPLATE_SELF_OPEN:
            case CruiseTemplateModel::SYS_TEMPLATE_SELF_CLOSE:
            case CruiseTemplateModel::SYS_TEMPLATE_SELF_WEEK:
            case CruiseTemplateModel::SYS_TEMPLATE_SELF_MONTH:

                $type   = CruiseTemplateModel::TYPE_8;
                $status = CruiseOrderModel::STATUS_NOT_SUBMIT;
                break;

            default:
                if (!$orderNo) {
                    $orderNo = (string)OpenShopMainProcessModel::query()->where('shopId', $shopId)->orderByDesc('id')->value('orderNo');
                }
                if ($sysTemplate == CruiseTemplateModel::SYS_TEMPLATE_COMMON) {
                    $status = CruiseOrderModel::STATUS_NOT_SUBMIT;
                } else {
                    if ($checkType == CruiseCheckDetailModel::CHECK_TYPE_INSIDE) {
                        $status = CruiseOrderModel::STATUS_NOT_SUBMIT;
                    } else {
                        $status = CruiseOrderModel::STATUS_COLLECTED;
                        if ($userId) {
                            // 添加流程进度  领取任务
                            $receiveTask = true;
                        }
                    }
                }
                $type = CruiseOrderModel::TYPE_CHECK;
        }


        //添加订单表
        $cruiseOrder                       = new CruiseOrderModel();
        $cruiseOrder->orderNo              = $orderNo;
        $cruiseOrder->shopId               = $shopId;
        $cruiseOrder->relationCode         = $relationCode;
        $cruiseOrder->type                 = $type;
        $cruiseOrder->status               = $status;
        $cruiseOrder->handlerId            = $userId;
        $cruiseOrder->templateId           = $templateId;
        $cruiseOrder->cruiseCheckCompanyId = $cruiseCheckCompanyId;
        $cruiseOrder->save();

        //添加日志表
        CruiseOrderProcessModel::initCruiseOrderProcess($cruiseOrder->id);

        //添加关联关系
        CruiseTaskOrderMappingModel::add($cruiseCheckTaskId, $cruiseOrder->id);


        //生成巡检报告
        $cruiseCheckDetail               = new CruiseCheckDetailModel();
        $cruiseCheckDetail->code         = KfSnow::nextIdCache();
        $cruiseCheckDetail->orderId      = $cruiseOrder->id;
        $cruiseCheckDetail->taskId       = $cruiseCheckTaskId;
        $cruiseCheckDetail->sysTemplate  = $sysTemplate;
        $cruiseCheckDetail->templateType = CruiseOrderModel::query()->where('id', $cruiseOrder->id)->value('type');
        $cruiseCheckDetail->checkType    = $checkType;
        $cruiseCheckDetail->reportResult = CruiseCheckDetailModel::REPORT_RESULT_INIT;
        $cruiseCheckDetail->veto         = CruiseCheckDetailModel::VETO_ON;
        $cruiseCheckDetail->templateId   = $templateId;
        $cruiseCheckDetail->taskName     = $cruiseOrder->getTaskName($cruiseCheckTaskId);

        if ($userId) {
            $cruiseCheckDetail->dealUid  = $userId;
            $cruiseCheckDetail->dealName = $dealName = RmsUserService::getRmsUserInfoByUserIds([$userId], [], true)['data'][0]['username'] ?? '';
        }

        if ($companyId) {
            $cruiseCheckDetail->companyId   = $companyId;
            $cruiseCheckDetail->companyName = FsCompanyModel::getCompanyNameByDepartmentId($companyId);
        }

        $cruiseCheckDetail->save();

        // 初始化cruise_order_inputs信息
        (new CheckInputService($cruiseOrder->id))->initOrderInput(true, $cruiseOrder->templateId);

        if ($receiveTask) {
            // 自动领取任务
            self::achieveSpecialTask($cruiseOrder->id, [
                'userId'   => $userId,
                'username' => $dealName
            ]);

            // 发送短信通知
            $sendSmsMobile = (new RmsUserApi())->getUserInfoByIds([$userId], ['mobile'])['data'][0]['mobile'] ?? '';
            if (strlen($sendSmsMobile)) {
                try {
                    CruiseCheckSmsService::sendInspectionTask($sendSmsMobile, 1, $cruiseCheckDetail->taskName, '待提交');
                } catch (\Exception $exception) {}
            }
        }

        return $cruiseOrder;
    }

    // 上次巡店时间
    public static function lastCruiseTime(int $pageSize, int $pageNum, array $shopIds = []): array
    {
        return CruiseOrderModel::query()
            ->when(count($shopIds), function ($query) use ($shopIds) {
                $query->whereIn('shopId', $shopIds);
            })
            ->join('cruise_check_details as detail', 'detail.orderId', '=', 'cruise_order.id')
            ->where('cruise_order.status', CruiseOrderModel::STATUS_COMPLETE)
            ->groupBy('cruise_order.shopId')
            ->select('cruise_order.shopId', DB::raw('max(detail.submitTime) as submitTime'))
            ->orderByDesc('cruise_order.id')
            ->when($pageSize, function ($query) use ($pageSize, $pageNum) {
                $query->forPage($pageNum, $pageSize);
            })
            ->get()
            ->toArray();
    }


    /**
     * 领取专项稽核任务
     * @param $id
     * @param $authInfo
     * @return void
     */
    public static function achieveSpecialTask($id, $authInfo)
    {
        //判断  避免同时领取
        $cruiseOrderQuery = CruiseOrderModel::query()
            ->where('id', $id)
            ->first();

        if (null == $cruiseOrderQuery) {
            throw new ResponseHttpException(BaseErrorCode::$ERROR_OCCURRED, null, "该任务不存在,领取任务失败");
        }

        if ($cruiseOrderQuery->status == CruiseOrderModel::STATUS_NOT_SUBMIT) {
            throw new ResponseHttpException(BaseErrorCode::$ERROR_OCCURRED, null, "该任务已被领取");
        }

        DB::beginTransaction();
        try {
            //通过Id获得cruise_check_details
            CruiseCheckDetailModel::query()
                ->where('orderId', $id)
                ->update([
                    'dealName' => $authInfo['username'],
                    'dealUid'  => $authInfo['userId'],
                ]);
            //修改状态  变为待提交
            CruiseOrderModel::query()
                ->where('id', $id)
                ->update([
                    'status'    => CruiseOrderModel::STATUS_NOT_SUBMIT,
                    'handlerId' => $authInfo['userId']
                ]);

            //添加流程进度
            CruiseOrderProcessModel::query()->insert([
                'cruiseOrderId' => $id,
                'step'          => CruiseOrderProcessModel::PROCESS_RECEIVE,
                'status'        => CruiseOrderProcessModel::STATUS_OK,
                'type'          => CruiseOrderModel::TYPE_CHECK,
                'createdByUid'  => $authInfo['userId'],
                'updatedByUid'  => $authInfo['userId'],
                'createdAt'     => time(),
                'updatedAt'     => time(),
            ]);
            DB::commit();
        } catch (\Exception $exception) {
            Log::warning($exception);
            DB::rollBack();
            throw new ResponseHttpException(BaseErrorCode::$ERROR_OCCURRED, null, "领取任务失败");
        }

        // 发送NSQ
        CruiseDisinfectService::aboutCruiseOrderChangedPublishNsq('belongedTo', $cruiseOrderQuery->toArray());

    }


    /**
     * 上传稽核人员照片
     * @param $authInfo
     * @param $photo
     * @return void
     */
    public static function updateCheckUserPhone($authInfo, $photo)
    {
        $photo = ltrim(parse_url($photo, PHP_URL_PATH), '/');
        (new RmsUserApi())->setUserFeishuIdNByteUserId($authInfo['userId'], ['photo' => $photo]);
    }


    /**
     * 获得稽核用户信息
     * @param $authInfo
     * @return array
     * @throws Exception
     */
    public static function getCheckUserInfo($authInfo): array
    {
        //获得稽核二维码
        $resourceModel = ResourcesModel::query()
            ->where('module', ResourcesModel::MODULE_TYPE_CHECK_USER_QRCODE)
            ->where('business', ResourcesModel::BUSINESS_CHECK_USER_QRCODE)
            ->where('name', 'checkQRCode')
            ->where('businessId', $authInfo['userId'])
            ->first();

        $qrCodeUrl = (string)optional($resourceModel)->url;
        $createdAt = (int)optional(optional($resourceModel)->createdAt)->timestamp;
        if (null == $resourceModel || !$qrCodeUrl || ($createdAt + 7 * 86400) < time()) {
            $qrCodeUrl = self::makeCheckQRCode($authInfo['userId'], self::CRUISE_CHECK_SCAN_QRCODE_AGREEMENT . 'param1=' . enAes128Ecb($authInfo['userId'], self::CRUISE_CHECK_KEY) . '&param2=' . enAes128Ecb((time() + 7 * 86400), self::CRUISE_CHECK_KEY));
        }
        $userInfo = (new RmsUserApi())->getUserInfoByIds([$authInfo['userId']])['data'][0] ?? [];
        return [
            'name'        => $userInfo['username'] ?? '-',
            'number'      => self::getCheckNoByUserId($authInfo['userId']),
            'position'    => '稽核专员',
            'photo'       => picturePath(($userInfo['photo'] ?? '4b/07/1e16179f2dfe445f9eaa559e81d204fd6c6f70049642a72dfd42108990dd.jpg')),
            'checkQRCode' => picturePath($qrCodeUrl),
        ];
    }


    /**
     * 生成二维码并保存
     * @param $userId
     * @param $content
     * @return mixed|string
     * @throws Exception
     */
    public static function makeCheckQRCode($userId, $content)
    {
        $file = (new MakeQRCodeService())->makeCheckQRCode($content) ?? [];
        ResourcesModel::moduleBusinessSingleResourcesUpdate(
            ResourcesModel::MODULE_TYPE_CHECK_USER_QRCODE,
            ResourcesModel::BUSINESS_CHECK_USER_QRCODE,
            'checkQRCode',
            $userId,
            [$file['path'] ?? ''],
            1
        );
        return $file['path'] ?? '';
    }


    //通过userID获得稽核人员编码
    public static function getCheckNoByUserId(int $userId = 0): string
    {
        $number = 99 * 728;   //72072
        return 'NO.' . str_pad(($userId + $number), 6, '0', STR_PAD_LEFT);
    }

    public static function superviseScore($params, $id, $userId, $score)
    {
        $data = [];
        collect($params)->map(function ($param) use (&$data) {
            $data = array_merge($data, [$param['field'] => $param['score']]);
        });
        (new CheckInputService($id, $userId))->auditDeductScores($data);
    }

    /**
     * 工厂任务去巡检
     * @throws GuzzleException
     */
    public static function addCompanyTask($cruiseCheckCompanyId, $taskId, $userId): array
    {
        //判断自检明细是否生成
        $selfTaskModel = CruiseCheckSelfDetailModel::query()
            ->where('cruiseCheckCompanyId', $cruiseCheckCompanyId)
            ->where('taskId', $taskId)
            ->where('date', Carbon::now()->format('Ymd'))
            ->first();

        if (null == $selfTaskModel) {
            $selfTaskId = CruiseCheckSelfDetailModel::query()
                ->create([
                    'cruiseCheckCompanyId' => $cruiseCheckCompanyId,
                    'templateType'         => CruiseTemplateModel::TYPE_5,
                    'taskId'               => $taskId,
                    'date'                 => Carbon::now()->format('Ymd'),
                    'status'               => CruiseCheckSelfDetailModel::STATUS_WAIT
                ])->id;
            return self::addTask(0, $userId, CruiseTemplateModel::TYPE_5, $selfTaskId);
        } else {
            return ['id' => $selfTaskModel->cruiseOrderId];
        }
    }

    // 夸父稽核-tab
    const CRUISE_TAB_MISSION = 1; // 代办
    const CRUISE_TAB_SHOP = 2; // 门店
    const CRUISE_TAB_REPORT = 3; // 报告
    const CRUISE_TAB_TEXT = [
        self::CRUISE_TAB_MISSION => '代办',
        self::CRUISE_TAB_SHOP => '门店',
        self::CRUISE_TAB_REPORT => '报告',
    ];

    /**
     * 稽核小程序tab权限
     * @param int $userId
     */
    public static function tabPermission(int $userId, array $permissionLists, string $appId): array
    {
        $platform = ConfigModel::getFsConfigByAppId($appId)['platformName'] ?? '';

        // 三方稽核
        if ($platform == 'cruiseCheckSupplier') {
            return [
                self::CRUISE_TAB_MISSION,
                self::CRUISE_TAB_REPORT,
            ];
        }

        // 夸父稽核
        $tabs = [self::CRUISE_TAB_REPORT];

        // 权限点
        if ($permissionLists) {

            if (in_array('cruise.mini.waitmission', $permissionLists)) {
                $tabs[] = self::CRUISE_TAB_MISSION;
            }

            if (in_array('cruise.mini.shop', $permissionLists)) {
                $tabs[] = self::CRUISE_TAB_SHOP;
            }
        }

        // 稽核督导
        $organizationUser = OpenShopOrganizationManageUserModel::query()->where('type', OpenShopOrganizationManageUserModel::TYPE_CHECK_MANAGER)->where('userId', $userId)->count();
        if ($organizationUser) {
            $tabs[] = self::CRUISE_TAB_MISSION;
            $tabs[] = self::CRUISE_TAB_SHOP;
            return $tabs;
        }

        // 品控
        if (in_array($userId, ConfigModel::getCruiseCheckAudit())) {
            $tabs[] = self::CRUISE_TAB_MISSION;
            $tabs[] = self::CRUISE_TAB_SHOP;
            return $tabs;
        }

        return $tabs;
    }

    /**
     * 可转交的用户列表
     * @param array $orderNos
     * @return array
     * @throws GuzzleException
     */
    public static function transferUsers(array $cruiseOrderIds): array
    {
        $detail = CruiseCheckDetailModel::query()->where('orderId', $cruiseOrderIds[0])->select('checkType', 'companyId')->first();
        if (!$detail) {
            BaseService::throwErr('订单详情不存在');
        }

        if (in_array($detail->checkType, [CruiseCheckDetailModel::CHECK_TYPE_COMMON, CruiseCheckDetailModel::CHECK_TYPE_INSIDE])) {

            // 总部组织架构
            return Cache::remember("fs_users_online", getSwitchCacheTime(600), function () {

                return KmsUser::query()
                              ->where('isExited', 0)
                              ->where('rmsUserId', '>', 0)
                              ->groupBy('rmsUserId')
                              ->select('rmsUserId', 'name', 'nickname')
                              ->orderBy('rmsUserId')
                              ->get()
                              ->map(function ($item) {
                                  return [
                                      'id'   => $item->rmsUserId,
                                      'name' => $item->name . '（' . $item->nickname . '）',
                                  ];
                              })->toArray();
            });

        } elseif ($detail->checkType == CruiseCheckDetailModel::CHECK_TYPE_THIRD_PARTY) {

            // 供应商
            $fsCompanyId = FsCompanyModel::query()
                                         ->where('departmentId', $detail->companyId)
                                         ->value('id');

            $rmsUserIds = FsCompanyUserMappingModel::query()
                                                   ->where('fsCompanyId', $fsCompanyId)
                                                   ->distinct()
                                                   ->pluck('rmsUserId')
                                                   ->toArray();

            return collect((new RmsUserApi())->getUserInfoByIds($rmsUserIds, ['id', 'username'])['data'] ?? [])
                ->map(function ($item) {
                    return [
                        'id'   => $item['id'],
                        'name' => $item['username'],
                    ];
                })->toArray();
        }

        return [];
    }

    /**
     * 移交任务
     * @param array $cruiseOrderIds
     * @return
     */
    public static function transfer(array $cruiseOrderIds, int $targetUserId): array
    {
        $errs = [];

        // 基础校验
        // 1. 只能转交待提交和待修改任务
        $cruiseOrders = CruiseOrderModel::query()->whereIn('id', $cruiseOrderIds)->get();

        $cruiseOrders
            ->whereNotIn('status', [CruiseOrderModel::STATUS_NOT_SUBMIT, CruiseOrderModel::STATUS_NOT_MODIFY])
            ->each(function (CruiseOrderModel $cruiseOrderModel) use (&$errs) {

                $shop = ShopModel::query()->find($cruiseOrderModel->shopId);
                if ($shop) {
                    $shopName = $shop->shopCode . $shop->name;
                } else {
                    $shopName = "id:{$cruiseOrderModel->shopId}";
                }

                $errs['title']     = '只能转交待提交和待修改任务，以下任务转交失败：';
                $errs['details'][] = "{$shopName}当前状态：" . (CruiseOrderModel::CRUISE_STATUS_MAPPING[$cruiseOrderModel->status] ?? '');
            });

        if ($errs) {
            return self::returnData(ErrCode::CODE_ERR_NO_TRANSFER_CRUISE, $errs['title'], $errs);
        }

        // 2. 必须是同一个组织下的任务
        $details = CruiseCheckDetailModel::query()
                                         ->with('cruiseOrderRel')
                                         ->whereIn('orderId', $cruiseOrderIds)
                                         ->where('templateType', CruiseTemplateModel::TYPE_3)
                                         ->get();

        if ($details->pluck('companyId')->unique()->count() > 1) {

            // 只能转交同一组织下的任务
            $details->each(function (CruiseCheckDetailModel $cruiseCheckDetailModel) use (&$errs) {

                $shop = ShopModel::query()->find($cruiseCheckDetailModel->cruiseOrderRel->shopId);
                if ($shop) {
                    $shopName = $shop->shopCode . $shop->name;
                } else {
                    $shopName = "id:{$cruiseCheckDetailModel->cruiseOrderRel->shopId}";
                }

                $companyName       = FsCompanyModel::getCompanyNameByDepartmentId($cruiseCheckDetailModel->companyId);
                $errs['title']     = '必须是同一个组织，以下任务转交失败：';
                $errs['details'][] = $shopName . "当前供应商：" . $companyName;
            });
        }

        if ($errs) {
            return self::returnData(ErrCode::CODE_ERR_NO_TRANSFER_CRUISE, $errs['title'], $errs);
        }

        // 变更处理人
        $targetUserInfo   = (new RmsUserApi())->getUserInfoByIds([$targetUserId], ['id', 'username', 'mobile'])['data'][0] ?? [];
        $targetUserMobile = $targetUserInfo['mobile'] ?? '';
        $targetUserName   = $targetUserInfo['username'] ?? '';

        CruiseOrderModel::query()
                        ->whereIn('id', $cruiseOrderIds)
                        ->get()
                        ->each(function (CruiseOrderModel $cruiseOrderModel) use ($targetUserId, $targetUserName, $targetUserMobile) {

                            DB::beginTransaction();

                            // cruise_order
                            $cruiseOrderModel->handlerId = $targetUserId;
                            $cruiseOrderModel->save();

                            // cruise_check_detail
                            $detailModel = CruiseCheckDetailModel::query()->where('orderId', $cruiseOrderModel->id)->first();
                            if ($detailModel) {
                                $detailModel->dealUid  = $targetUserId;
                                $detailModel->dealName = $targetUserName;
                                $detailModel->save();
                            }

                            // 日志
                            // 插入process记录
                            $processId = CruiseOrderProcessModel::query()->create([
                                'cruiseOrderId' => $cruiseOrderModel->id,
                                'step'          => CruiseOrderProcessModel::PROCESS_TRANSFER,
                                'status'        => CruiseOrderProcessModel::STATUS_OK,
                                'type'          => $cruiseOrderModel->type,
                            ])->id;

                            // 插入examine记录
                            CruiseOrderExamineLogModel::query()->create([
                                'processId' => $processId,
                                'content'   => "新处理人：{$targetUserName}",
                                'status'    => $cruiseOrderModel->type,
                            ]);

                            DB::commit();

                            // 发送被转交人短信通知
                            if (strlen($targetUserMobile)) {
                                try {
                                    CruiseCheckSmsService::sendInspectionTask($targetUserMobile, 1, $detailModel->taskName, '待处理', '转交');
                                } catch (\Exception $exception) {}
                            }
                        });

        return self::returnData(0);
    }
}
